use tauri::{command, AppHandle, Runtime};

use crate::models::*;
use crate::LibsqlExt;
use crate::Result;

#[command]
pub(crate) async fn connect<R: Runtime>(
    app: AppHandle<R>,
    options: ConnectOptions,
) -> Result<ConnectionId> {
    let id = app.libsql().connect(options).await?;
    Ok(ConnectionId(id))
}

#[command]
pub(crate) async fn execute<R: Runtime>(app: AppHandle<R>, options: ExecuteOptions) -> Result<u64> {
    app.libsql().execute(options).await
}

#[command]
pub(crate) async fn query<R: Runtime>(
    app: AppHandle<R>,
    options: QueryOptions,
) -> Result<QueryResult> {
    app.libsql().query(options).await
}

#[command]
pub(crate) async fn sync<R: Runtime>(app: AppHandle<R>, options: SyncOptions) -> Result<()> {
    app.libsql().sync(options).await
}

#[command]
pub(crate) async fn close<R: Runtime>(app: AppHandle<R>, options: CloseOptions) -> Result<()> {
    app.libsql().close(options).await
}

// Vector operations commands

#[command]
pub(crate) async fn vector_top_k<R: Runtime>(
    app: AppHandle<R>,
    options: VectorTopKOptions,
) -> Result<QueryResult> {
    app.libsql().vector_top_k(options).await
}

#[command]
pub(crate) async fn vector_distance_cos<R: Runtime>(
    app: AppHandle<R>,
    connection_id: String,
    vector1: Value,
    vector2: Value,
) -> Result<f64> {
    app.libsql().vector_distance_cos(connection_id, vector1, vector2).await
}

#[command]
pub(crate) async fn vector_distance_l2<R: Runtime>(
    app: AppHandle<R>,
    connection_id: String,
    vector1: Value,
    vector2: Value,
) -> Result<f64> {
    app.libsql().vector_distance_l2(connection_id, vector1, vector2).await
}

#[command]
pub(crate) async fn vector_extract<R: Runtime>(
    app: AppHandle<R>,
    connection_id: String,
    vector_blob: Vec<u8>,
) -> Result<Vec<f32>> {
    app.libsql().vector_extract(connection_id, vector_blob).await
}

#[command]
pub(crate) async fn create_vector_index<R: Runtime>(
    app: AppHandle<R>,
    connection_id: String,
    index_name: String,
    table_name: String,
    column_name: String,
    settings: Option<Vec<String>>,
) -> Result<ExecuteResult> {
    app.libsql().create_vector_index(connection_id, index_name, table_name, column_name, settings).await
}
